//
//  CZSlideView.m
//  004-图片轮播器
//
//  Created by apple on 16/4/27.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "CZSlideView.h"
#import "CZSlideCell.h"
#import "Masonry.h"
#import "CZAdditions.h"

/**
 * 可重用标识符号
 */
static NSString *cellId = @"cellId";

/**
 * 数据放大基数
 */
#define kDataScaleSeed 10

#pragma mark - 轮播器布局
/**
 轮播器布局 - 仅为当前类服务和使用，外部无法访问
 */
@interface CZSlideLayout: UICollectionViewFlowLayout

@end

@implementation CZSlideLayout

- (void)prepareLayout {
    [super prepareLayout];
    
    // 设置 itemSize
    self.itemSize = self.collectionView.bounds.size;
    // 设置间距
    self.minimumLineSpacing = 0;
    self.minimumInteritemSpacing = 0;
    
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
}

@end

#pragma mark - 轮播器视图
@interface CZSlideView() <UICollectionViewDataSource, UICollectionViewDelegate>
/**
 * 集合视图
 */
@property (nonatomic, weak) UICollectionView *collectionView;
/**
 * 分页控件
 */
@property (nonatomic, weak) UIPageControl *pageControl;
@end

@implementation CZSlideView {
    /**
     * 定时器
     */
    NSTimer *_timer;
    /**
     * 定时器触发时间
     */
    NSTimeInterval _timerDuration;
}

// 纯代码的入口
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setupUI];
    }
    return self;
}

// XIB 的入口
- (void)awakeFromNib {
    [self setupUI];
}

// 从父视图删除
- (void)removeFromSuperview {
    [super removeFromSuperview];
    
    NSLog(@"%s", __FUNCTION__);
    // 取消时钟，从运行循环删除
    [_timer invalidate];
}

// 对象释放的时候会执行
/**
 添加了时钟 & 运行循环，dealloc 方法不会被调用！
 */
- (void)dealloc {
    
    NSLog(@"%s", __FUNCTION__);
}

#pragma mark - 设置数据
/**
 如果 collectionView 已经完成了数据显示！
 
 此时数据发生变化，如果`不做特殊处理`，collectionView 不会自动更新！
 
 数据发生变化后，通知 collectionView `重新加载数据` reloadData
 */
- (void)setImageUrls:(NSArray<NSURL *> *)imageUrls {
    _imageUrls = imageUrls;
    
    if (imageUrls.count == 0) {
        return;
    }
    if (_timer != nil) {
        return;
    }
    // 重新加载数据 - 再次调用数据源方法
    [_collectionView reloadData];
    
    // 1. 设置 collectionView 的位置 －> imageUrls.count
    // 方法 1: contentOffset
//    CGFloat width = _collectionView.bounds.size.width;
//    CGFloat offsetX = _imageUrls.count * width;
//    
//    // 设置偏移位置！
//    _collectionView.contentOffset = CGPointMake(offsetX, 0);
    // 方法 2: collectionView
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:_imageUrls.count * kDataScaleSeed inSection:0];
    
    [_collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    
    // 2. 设置分页控件
    _pageControl.currentPage = 0;
    _pageControl.numberOfPages = _imageUrls.count;
    
    // 3. 设置时钟，定时器
    /**
     参数：
     1. 时间间隔，多长时间触发一次时钟
     2. target: 监听时钟事件的对象
     3. selector: 当定时器触发时，调用的监听方法
     4. userInfo: 当时钟触发的时候，传递给监听方法的对象，通常 nil
     5. repeats: 是否重复触发
     
     scheduledTimerWithTimeInterval 本质上，就是以下两句代码的缩写！
     */
//    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];
    // 1> 创建时钟`对象`
    _timerDuration = 1.5;
    _timer = [NSTimer timerWithTimeInterval:_timerDuration target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];
    // 2> 将时钟添加到 运行循环
    // 默认的运行循环模式 NSDefaultRunLoopMode，在滚动状态下，不会监听
    // 如果有其它的滚动视图滚动，监听方法会暂停！
//    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    // NSRunLoopCommonModes：是一个数组，包含了`默认` 和 `滚动` 两种模式，无论是否滚动，监听方法都会执行！
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}

/**
 * 时钟触发方法
 */
- (void)updateTimer {
    
    if (self.window == nil) {
        return;
    }
    
    NSLog(@"%s", __FUNCTION__);
    
    // 工作：图片轮播器 indexPath.item 需要`递增`
    // 1. 取出当前显示的 indexPath
    // Visible 可见
    NSIndexPath *indexPath = [_collectionView indexPathsForVisibleItems].lastObject;
    
    // 2. 将 indexPath.item + 1
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:indexPath.item + 1 inSection:indexPath.section];
    
    // 3. 设置 collectionView 滚动位置 新的 indexPath
    // 通过代码设置图片轮播器的滚动位置，不会触发滚动视图`停止代理方法`！
    // 会触发 scrollViewDidEndScrollingAnimation 代理方法！
    [_collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}

#pragma mark - UICollectionViewDataSource 数据源协议方法！
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return _imageUrls.count * kDataScaleSeed * 2;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    CZSlideCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];
    
//    cell.backgroundColor = [UIColor cz_randomColor];
    // 让 cell 显示图像
    // 需要调整 indexPath.item，取余数，始终不会超过上限
    NSInteger index = indexPath.item % _imageUrls.count;
    
    cell.imageUrl = _imageUrls[index];

    // 只有两个 cell!
//    NSLog(@"%@", cell);
    
    return cell;
}

#pragma mark - UICollectionViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // 0. 如果没有数据，直接返回
    if (_imageUrls.count == 0) {
        return;
    }
    
    // 1. 计算分页的偏移量
    CGFloat offsetX = scrollView.contentOffset.x / scrollView.bounds.size.width;
    
    // 2. 根据 offsetX 四舍五入计算页数
    NSInteger page = (NSInteger)(offsetX + 0.5);
    
    // 3. 根据数组数量，取余数
    page = page % _imageUrls.count;
    
//    NSLog(@"%zd", page);
    
    _pageControl.currentPage = page;
}

/**
 * 通过设置 contentOffset 动画滚动完成之后调用
 */
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
//    NSLog(@"%s", __FUNCTION__);
    // 主动调用动画停止代理方法
    [self scrollViewDidEndDecelerating:scrollView];
}

/**
 * 滚动视图停止滚动会调用
 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    
    // 根据 contentOffset.x 判断页数
    NSInteger page = scrollView.contentOffset.x / scrollView.bounds.size.width;
    
    // lastItem = _imageUrl.count * 2
    NSInteger lastItem = [_collectionView numberOfItemsInSection:0];
    
    NSLog(@"第 %zd 页 - lastItem %zd", page, lastItem);
    // 只处理第 0 页，和最后一页
    if (page == 0 || page == (lastItem - 1)) {
        // 如果是 0 页，跳转到 _imageUrl.count
        // 如果是最后一页，跳转到 _imageUrl.count - 1
        NSInteger offset = _imageUrls.count * kDataScaleSeed;
        
        // 判断最后一页
        if (page == (lastItem - 1)) {
            offset = offset - 1;            // (5 - 1) * 10 = 40 // 5 * 10 - 1
        }
        
        // 设置 contentOffset
        NSLog(@"我要跳转到 %zd", offset);
        
        CGFloat width = scrollView.bounds.size.width;
        
        scrollView.contentOffset = CGPointMake(offset * width, 0);
    }
}

// 开始拖，暂停时钟！
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    NSLog(@"开始拖，暂停时钟到永远 %@", [NSDate distantFuture]);
    _timer.fireDate = [NSDate distantFuture];
}

// 结束拖，继续时钟！
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    NSLog(@"结束拖，恢复时钟，从现在开始，2s 后继续时钟！");
    _timer.fireDate = [NSDate dateWithTimeIntervalSinceNow:_timerDuration];
}

#pragma mark - 设置界面
- (void)setupUI {
    
    // 1. 添加控件
    // 1> collectionView
    CZSlideLayout *layout = [[CZSlideLayout alloc] init];
    UICollectionView *cv = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
    
    [self addSubview:cv];
    
    // 设置
    // 注册原型 cell
    [cv registerClass:[CZSlideCell class] forCellWithReuseIdentifier:cellId];
    
    // 设置数据源
    cv.dataSource = self;
    // 设置代理
    cv.delegate = self;
    
    // 设置显示属性
    cv.pagingEnabled = YES;
    cv.showsVerticalScrollIndicator = NO;
    cv.showsHorizontalScrollIndicator = NO;
    // 关闭弹簧效果
    cv.bounces = NO;
    
    // 2> pageControl
    UIPageControl *pager = [[UIPageControl alloc] init];
    
    // 设置
    pager.numberOfPages = 0;
    pager.currentPage = 0;
    pager.currentPageIndicatorTintColor = [UIColor yellowColor];
    pager.pageIndicatorTintColor = [UIColor redColor];
    
    // 取消用户交互
    pager.userInteractionEnabled = NO;
    
    [self addSubview:pager];
    
    // 2. 自动布局
    [cv mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self);
    }];
    
    [pager mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self);
        make.bottom.mas_equalTo(-4);
    }];
    
    // 3. 记录成员变量
    _collectionView = cv;
    _pageControl = pager;
}

@end
